home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
async1.zip
/
ASYNC.DOC
< prev
next >
Wrap
Text File
|
1985-09-13
|
14KB
|
276 lines
Async.Asm
Operation Notes
by Jerry D. Stuckle
Userid: 72205,234
Async.Asm is an example assembler program to drive the Asynchronous Adapter
in the IBM-PC. It accepts the same parameters as the ROM BIOS Interrupt 14
code, with the exception that only one port (COM1:) is available. The code
can be easily modified to handle two communications ports, but for 1 only
wrote the code for one port to keep things simple.
This routine provides a buffered byte-stream interface to the
communications port. The following parameters can be used.
AH=0 Open communications port.
AL has initialization parameters
7 6 5 4 3 2 1 0
----Baud Rate---- --Parity-- -Stop- -Word Len-
000 - 110 X0 - None 0 - 1 00 - 5 bits
001 - 150 01 - Odd 1 - 2 01 - 6 bits
010 - 300 11 - Even 10 - 7 bits
011 - 600 11 - 8 bits
100 - 1200
101 - 2400
110 - 4800
111 - 9600
On return, conditions set as in call to comm status (AH=3)
AH=1 Send the character in AL to the port. (AL is preserved). On exit,
Bit 7 of AH is set if the buffer is full. If Bit 7 of AH is not set, the
remainder of AH is set as in status request, reflecting the current status of
the line.
AH=2 Receive a character in AL from the port before returning to the
caller. On Exit, if AH is 0FF, the buffer was found to be empty and AL is
indeterminate. Otherwise, AH has the current line status as set by the status
routine, except the only bits left on are the error bits (7,4,3,2,1). If AH
has bit 7 on (time out) the remaining bits are unpredictable. Thus, AH is
non-zero only if errors have occurred.
AH=3 Return the port status in AX.
AH contains the line status
Bit 7 = Time out
Bit 6 = Trans buffer empty
Bit 5 = Trans buffer not full
Bit 4 = Break detect
Bit 3 = Framing error
Bit 2 = Parity error
Bit 1 = Receive buffer overrun
Bit 0 = Data ready in receive buffer
AH=FF = Invalid parameter in request.
AL contains the modem status
Bit 7 = Received line signal detect
Bit 6 = Ring indicator
Bit 5 = Data set ready
Bit 4 = Clear to send
Bit 3 = Delta receive line signal detect
Bit 2 = Trailing edge ring indicator
Bit 1 = Delta data set ready
Bit 0 = Delta clear to send
AH=4 Close communications port. Resets the communications line and flushes
the buffers.
For all values of AH. DX = parameter indicating which communications port
to use (0 allowed).
Other than AX, all other registers returned unchanged for all calls.
Note: The following changes have been made from the BIOS interrupt 14
driver:
1: This routine is completely interrupt driven, with transmit and receive
buffers so the program does not have to wait for data.
2: Function call 0 (Initialize) will immediately return control to the
program. It is the programmer's responsibility to ensure the port is actually
ready before sending data, although data can be sent. This allows the program
to open the port with no carrier received.
3: AH=1 will return with Bit 7 of AH set only if the transmit buffer is
full. Otherwise, the character will be placed in the buffer and transmitted
when the port catches up with the buffer.
4: AH=4 is a new call. It will disable the interrupts and flush the
transmit and receive buffers. It should be called before program termination
to disable the port.
5: On all calls, the following bits in AH have changed:
Bit 6 is now Transmit buffer empty.
Bit 5 is now Transmit buffer not full.
Bit 1 is now Receive buffer overrun.
Bit 0 is now Receive buffer not empty.
These bits correspond to equivalent bits in the original code, i.e. Bit 0
was Data ready, and now indicates something in the receive buffer (data
ready).
The receive buffer overrun bit should not occur, if the receive buffer is
large enough and called frequently enough. If it does occur, the buffer data
is still good, but data will be missing and integrity compromised. The data
will be lost starting X bytes past the current buffer, where X is the buffer
size.
The program was written in a modular form, with mainline code performing
parameter verification checks and routine selection. All work is done in
procedures. Some simple macros are included for commonly used functions, and
the transmit and receive buffers are defined using a structure.
Also, I like to use both upper and lower case characters for coding in
assembler. All registers are in upper case only (AX,BX, etc.) while
everything else is capitalized (Functble, Cinit, etc.). I feel this makes the
code more readable, but it is up to the programmer writing the code what
format he/she uses. The only time it will make a difference is in comparing
parameters in a macro call (I.E. using the Ifidn <A>,<a>). This function is
case sensitive, and will fail in the example above.
Since we are working with mostly bytes and port address, this routine uses
.Radix 16. It could have also been written with the default of .Radix 10, but
then many values would have had to have an 'h' (hexadecimal) notation
following. As it stands, the only values which need the 'h' appended are
those ending in a 'b' or 'd', which would otherwise signify binary or decimal
representation, respectively.
There are two main procedures in the code. Int14 is the interrupt 14
handler, and is the user interface to the program. It replaces the existing
Int14 handler in BIOS and DOS, and for the most part contains the same
functions as the original handler. (See Async.Doc for specific information).
The other main procedure is Int0C, which is the machine's interface. It
uses the machine's hardware interrupt 0C from the communications port to drive
it. When status changes (i.e. character received, modem dropped ready, etc.)
the Int0C code is driven to handle the resultant hardware interrupt. This
allows the program to update the buffers and/or status indicators when they
occur, and relieves the program of the need to check except when it is ready
to receive the data.
The macros used in the program are defined at the beginning. These macros
are used in place of coding common code several times in the program, saving
time and the possibility of "finger checks". They also make reading the code
and debugging easier. The macros will expand in the listing of the code, so
you can see exactly what is generated for later debugging.
Liberal use of Subttl and Page pseudo-ops have been used to make output
formatting logical and easier to read. I have found the time saved trying to
find an area of code is much worth the few pages of extra paper used in a
large program. Also, it starts a procedure at the top of the page instead of
in the middle, making it easier to find later.
Unless absolutely necessary, all jumps should be in a forward direction. If
a jump must be made backwards (occasionally necessary for looping), it should
be as short a distance as possible. This will minimize the possibility of
loops which cannot be exited, and the resultant reboot which will be
necessary.
One other note: It is possible to program in a structured fashion in MASM,
if procedures are used effectively. The use of a procedure does not mean it
is called from multiple places in the program. Rather, it should be a logical
and complete unit or work - that is, a specific function should be desired
upon entry, and that function completed at the end. This modularity can allow
some common routines to be used in other programs, and definitely makes the
code easier to write and debug.
Operatio